package cn.exrick.xboot.modules.Information.controller;

import cn.exrick.xboot.common.utils.HibernateProxyTypeAdapter;
import cn.exrick.xboot.common.utils.PageUtil;
import cn.exrick.xboot.common.utils.ResultUtil;
import cn.exrick.xboot.common.utils.SecurityUtil;
import cn.exrick.xboot.common.vo.PageVo;
import cn.exrick.xboot.common.vo.Result;
import cn.exrick.xboot.modules.Information.entity.*;
import cn.exrick.xboot.modules.Information.service.IRiverTourHistoryService;
import cn.exrick.xboot.modules.activiti.entity.business.EventReport;
import cn.exrick.xboot.modules.activiti.entity.business.RiverAvg;
import cn.exrick.xboot.modules.base.entity.Department;
import cn.exrick.xboot.modules.base.entity.User;
import cn.exrick.xboot.modules.base.service.DepartmentService;
import cn.exrick.xboot.modules.util.GPSDistance;
import cn.exrick.xboot.modules.webSocket.MyHandler;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.socket.TextMessage;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author lijian
 */
@Slf4j
@RestController
@Api(description = "巡河历史表管理接口")
@RequestMapping("/xboot/riverTourHistory")
@Transactional
public class RiverTourHistoryController {

    @Autowired
    private IRiverTourHistoryService iRiverTourHistoryService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private DepartmentService departmentService;

    @Autowired
    MyHandler myHandler;

    @Autowired
    private SecurityUtil securityUtil;

    @RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
    @ApiOperation(value = "通过id获取")
    public Result<RiverTourHistory> get(@PathVariable Long id){

        RiverTourHistory riverTourHistory = iRiverTourHistoryService.getById(id);
        return new ResultUtil<RiverTourHistory>().setData(riverTourHistory);
    }

    @RequestMapping(value = "/getAll", method = RequestMethod.GET)
    @ApiOperation(value = "获取全部数据")
    public Result<List<RiverTourHistory>> getAll(){

        List<RiverTourHistory> list = iRiverTourHistoryService.list();
        return new ResultUtil<List<RiverTourHistory>>().setData(list);
    }

    @RequestMapping(value = "/getByPage", method = RequestMethod.GET)
    @ApiOperation(value = "分页获取")
    public Result<IPage<RiverTourHistory>> getByPage(@ModelAttribute RiverTourHistory riverTourHistory,@ModelAttribute PageVo page){
        QueryWrapper<RiverTourHistory> qw = new QueryWrapper<RiverTourHistory>();
        if(riverTourHistory.getPatrolUser() != null && !"".equals(riverTourHistory.getPatrolUser())){
            qw.like("patrol_user",riverTourHistory.getPatrolUser());
        }
        if(riverTourHistory.getPatrolStartTime() != null && !"".equals(riverTourHistory.getPatrolStartTime())){
            SimpleDateFormat sdf =   new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
            String str = sdf.format(riverTourHistory.getPatrolStartTime());
            qw.apply("UNIX_TIMESTAMP(patrol_start_time) >=UNIX_TIMESTAMP('"+str+"')");
        }
        if(riverTourHistory.getPatrolEndTime() != null && !"".equals(riverTourHistory.getPatrolEndTime())){
            SimpleDateFormat sdf =   new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
            String str = sdf.format(riverTourHistory.getPatrolEndTime());
            qw.apply("UNIX_TIMESTAMP(patrol_end_time) <=UNIX_TIMESTAMP('"+str+"')");
        }
        //按照部门查找
        if(riverTourHistory.getDepartmentId() != null && !"".equals(riverTourHistory.getDepartmentId())){
            String departmentId = securityUtil.getCurrUser().getDepartmentId();
            String zero = departmentService.get(departmentId).getParentId();
            if (!"0".equals(zero)){
                Boolean boo = false;
                List<Department> parentId = departmentService.findParentId(departmentId);
                for (Department dep: parentId){
                    if (dep.getId().equals(riverTourHistory.getDepartmentId())){
                        boo = true;
                        break;
                    }
                }
                String id = departmentService.get(riverTourHistory.getDepartmentId()).getParentId();
                if (departmentId.equals(riverTourHistory.getDepartmentId())||boo){
                    qw.inSql("user_id", "SELECT u.id FROM t_user u LEFT JOIN t_department d on u.department_id = d.id where d.parent_id="+riverTourHistory.getDepartmentId()+" or d.id="+riverTourHistory.getDepartmentId() );
                }else if ("0".equals(id)){
                    qw.inSql("user_id", "SELECT u.id FROM t_user u LEFT JOIN t_department d on u.department_id = d.id where d.parent_id="+departmentId+" or d.id="+departmentId );
                }else {
                    qw.in("user_id","-1");
                }
            }else {
                if (!departmentId.equals(riverTourHistory.getDepartmentId())) {
                    qw.inSql("user_id", "SELECT u.id FROM t_user u LEFT JOIN t_department d on u.department_id = d.id where d.parent_id="+riverTourHistory.getDepartmentId()+" or d.id="+riverTourHistory.getDepartmentId() );
                }
            }
           // qw.inSql("user_id","SELECT id FROM t_user WHERE department_id ="+riverTourHistory.getDepartmentId());
        }else{
            String departmentId = securityUtil.getCurrUser().getDepartmentId();
            String zero = departmentService.get(departmentId).getParentId();
            if (!"0".equals(zero)){
                qw.inSql("user_id", "SELECT u.id FROM t_user u LEFT JOIN t_department d on u.department_id = d.id where d.parent_id="+departmentId+" or d.id="+departmentId );
            }
        }
        qw.orderByDesc ( "id" );
        IPage<RiverTourHistory> data = iRiverTourHistoryService.page(PageUtil.initMpPage(page),qw);
        return new ResultUtil<IPage<RiverTourHistory>>().setData(data);
    }

    @RequestMapping(value = "/getByPage1", method = RequestMethod.GET)
    @ApiOperation(value = "导出数据获取")
    public Result< Map<String,Object>> getByPage1(@ModelAttribute RiverTourHistory riverTourHistory,@ModelAttribute PageVo page){
        QueryWrapper<RiverTourHistory> qw = new QueryWrapper<RiverTourHistory>();
        if(riverTourHistory.getPatrolUser() != null && !"".equals(riverTourHistory.getPatrolUser())){
            qw.like("patrol_user",riverTourHistory.getPatrolUser());
        }
        if(riverTourHistory.getPatrolStartTime() != null && !"".equals(riverTourHistory.getPatrolStartTime())){
            SimpleDateFormat sdf =   new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
            String str = sdf.format(riverTourHistory.getPatrolStartTime());
            qw.apply("UNIX_TIMESTAMP(patrol_start_time) >=UNIX_TIMESTAMP('"+str+"')");
        }
        if(riverTourHistory.getPatrolEndTime() != null && !"".equals(riverTourHistory.getPatrolEndTime())){
            SimpleDateFormat sdf =   new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
            String str = sdf.format(riverTourHistory.getPatrolEndTime());
            qw.apply("UNIX_TIMESTAMP(patrol_end_time) <=UNIX_TIMESTAMP('"+str+"')");
        }
        if(riverTourHistory.getDepartmentId() != null && !"".equals(riverTourHistory.getDepartmentId())){
            qw.inSql("user_id","SELECT id FROM t_user WHERE department_id ="+riverTourHistory.getDepartmentId());
        }else{
            String departmentId = securityUtil.getCurrUser().getDepartmentId();
            String zero = departmentService.get(departmentId).getParentId();
            if (!"0".equals(zero)){
                qw.inSql("user_id", "SELECT u.id FROM t_user u LEFT JOIN t_department d on u.department_id = d.id where d.parent_id="+departmentId+" or d.id="+departmentId );
            }
        }
        qw.orderByDesc ( "id" );
        List <RiverTourHistory> list = iRiverTourHistoryService.list ( qw );
        /**
         * 将查询的数据添加到map
         */
        Map<String,Object> map  = new HashMap <>();
        map.put ( "river", list);
        /**
         * 根据部门id获取名称，默认名称是巡河历史。
         */
        Department department = new Department();
        department.setTitle ( "巡河历史 " );
        if(riverTourHistory.getDepartmentId() != null && !"".equals(riverTourHistory.getDepartmentId())) {
             department = departmentService.get ( riverTourHistory.getDepartmentId());
        }
        map.put( "deptName", department.getTitle());
        return new ResultUtil<Map<String,Object>>().setData(map);
    }

    @RequestMapping(value = "/delByIds/{ids}", method = RequestMethod.DELETE)
    @ApiOperation(value = "批量通过id删除")
    public Result<Object> delAllByIds(@PathVariable Long[] ids){

        for(Long id : ids){
            iRiverTourHistoryService.removeById(id);
        }
        return new ResultUtil<Object>().setSuccessMsg("批量通过id删除数据成功");
    }

/*********************************************************************************** 巡河处理 *****************************************************************************************/

    @RequestMapping(value = "/insertOrUpdate", method = RequestMethod.POST)
    @ApiOperation(value = "保存或更新数据")
    public Result<RiverTourHistory> saveOrUpdate(@ModelAttribute RiverTourHistory riverTourHistory){
        if(riverTourHistory.getRiverName() == null || riverTourHistory.getRiverName().equals("")){
            log.info("接收（"+riverTourHistory.getPatrolUser()+"）开始巡河上报数据："+ riverTourHistory.toString());
        }else{
            log.info("接收（"+riverTourHistory.getId()+"）结束巡河上报数据："+ riverTourHistory.toString());
            String key = "gps::" + riverTourHistory.getId();
            String getGps = redisTemplate.opsForValue().get(key);
            if(StrUtil.isNotBlank(getGps)){
                getGps = getGps.replace("{", "[");
                getGps = getGps.replace("}", "]");
                getGps = getGps.replace("\"","");
                getGps = getGps.replace("lng:", "");
                getGps = getGps.replace("lat:", "");
                int numPatrolCourse = GPSDistance.couuntGps(getGps);
                try {
                    double val = Double.parseDouble(riverTourHistory.getPatrolCourse());
                    numPatrolCourse = numPatrolCourse > val?numPatrolCourse:(int)val;
                }catch (Exception e){}
                finally {
                    riverTourHistory.setPatrolCourse("" + numPatrolCourse);
                }
                riverTourHistory.setLocus(getGps);
                //删除redis缓存
                Set<String> keysGpsData = redisTemplate.keys(key);
                redisTemplate.delete(keysGpsData);

                //时间与里程
                String timePatrolKey = "gpsTimePatrol::" + riverTourHistory.getId();
                Set<String> keysTimePatrolData = redisTemplate.keys(timePatrolKey);
                redisTemplate.delete(keysTimePatrolData);
            }else{
                log.info("巡河人（"+riverTourHistory.getId()+"_"+riverTourHistory.getPatrolUser()+"）无坐标记录上传");
            }
        }
        if(iRiverTourHistoryService.saveOrUpdate(riverTourHistory)){
            //websocket向客户端推送数据
            myHandler.sendMessageToAllUsers(new TextMessage(""));
            return new ResultUtil<RiverTourHistory>().setData(riverTourHistory);
        }
        return new ResultUtil<RiverTourHistory>().setErrorMsg("操作失败");
    }

    @RequestMapping(value = "/realGps", method = RequestMethod.POST)
    @ApiOperation(value = "接收实时上报坐标")
    public void realGps(@RequestBody String json){

        //json数据转实体类巡河数据ID
        RealPatrolId rpi = JSON.parseObject(json,RealPatrolId.class);
        if(!rpi.getLat().equals("") && !rpi.getLng().equals("")){

            /**************************************************   gps   ***************************************************/

            List<Gps> gpsList = new ArrayList<>();
            //json数据转实体类经纬度
            Gps gps = JSON.parseObject(json,Gps.class);
            //定义key
            String gpsKey = "gps::" + rpi.getDataId();
            //取出redis缓存记录
            String getGps = redisTemplate.opsForValue().get(gpsKey);
            if(StrUtil.isNotBlank(getGps)){
                gpsList = new Gson().fromJson(getGps, new TypeToken<List<Gps>>(){}.getType());
            }
            gpsList.add(gps);

            //删除redis缓存
            Set<String> keysGpsData = redisTemplate.keys(gpsKey);
            redisTemplate.delete(keysGpsData);
            //在存回去
            redisTemplate.opsForValue().set(gpsKey, new GsonBuilder().registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY).create().toJson(gpsList));

            /***********************************************   时间与里程   ************************************************/

            List<RealGps> timePatrollist = new ArrayList<>();
            //json数据转实体类
            RealGps timePatrol = JSON.parseObject(json,RealGps.class);
            //定义key
            String timePatrolKey = "gpsTimePatrol::" + rpi.getDataId();
            //取出redis缓存记录
            String getTimePatrol = redisTemplate.opsForValue().get(timePatrolKey);
            if(StrUtil.isNotBlank(getTimePatrol)){
                timePatrollist = new Gson().fromJson(getTimePatrol, new TypeToken<List<RealGps>>(){}.getType());
            }
            timePatrollist.add(timePatrol);

            //删除redis缓存
            Set<String> keysTimePatrolData = redisTemplate.keys(timePatrolKey);
            redisTemplate.delete(keysTimePatrolData);
            //在存回去
            redisTemplate.opsForValue().set(timePatrolKey, new GsonBuilder().registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY).create().toJson(timePatrollist));
        }

    }

    @RequestMapping(value = "/getDateUserName", method = RequestMethod.GET)
    @ApiOperation(value = "通过当前巡河人员获取当天未结束巡河数据")
    public Result<List<RiverTourHistory>> getDateUserName(String userName){
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String date = format.format(new Date());
        List<RiverTourHistory> list = iRiverTourHistoryService.getDateUserName(userName,date);
        log.info("查询当前（"+userName+"）巡河人巡河记录："+ JSON.toJSONString(list));
        if(list.size()>0){
            //取出redis缓存记录
            List<RealGps> listTimePatrol = new ArrayList<>();
            String key = "gpsTimePatrol::" + list.get(0).getId();
            String getTimePatrol = redisTemplate.opsForValue().get(key);
            if(StrUtil.isNotBlank(getTimePatrol)){
                listTimePatrol = new Gson().fromJson(getTimePatrol, new TypeToken<List<RealGps>>(){}.getType());
                list.get(0).setPatrolCourse(listTimePatrol.get(listTimePatrol.size()-1).getPatrolCourse());
                list.get(0).setPatrolSpeed(listTimePatrol.get(listTimePatrol.size()-1).getPatrolSpeed());
                log.info("返回当前（"+userName+"）巡河人巡河记录" + JSON.toJSONString(list));
            }else{
                log.info("未查询到当前（"+userName+"）巡河人有巡河坐标上传");
            }
        }

        return new ResultUtil<List<RiverTourHistory>>().setData(list);
    }


    @RequestMapping(value = "/queryRiverHistoryByDate", method = RequestMethod.GET)
    @ApiOperation(value = "批量通过id删除")
    public Result<List<RiverTourHistory>> queryRiverHistoryByDate(@RequestParam Map map){
        List<RiverTourHistory> river = iRiverTourHistoryService.queryRiverHistoryByDateAll(map);
        return new ResultUtil<List<RiverTourHistory>>().setData(river);
    }

    @RequestMapping(value = "/getXcCount", method = RequestMethod.GET)
    @ApiOperation(value = "获取巡河总次数")
    public Result<Object> findAll(){
      Integer count = iRiverTourHistoryService.findTimeAll();
       return new ResultUtil<Object>().setData(count);
    }


    @RequestMapping(value = "/getXhCount", method = RequestMethod.GET)
    @ApiOperation(value = "获取巡河总公里数")
    public Result<Object> findKmAll(){
        String count = iRiverTourHistoryService.findKmAll();
        return new ResultUtil<Object>().setData(count);
    }

    @RequestMapping(value = "/getXcCharts", method = RequestMethod.GET)
    @ApiOperation(value = "获取巡查村统计人数")
    public Result<List<Map>> findXcCharts(){
        //获取集合
        List<Map> count = iRiverTourHistoryService.findXcCharts();
        return new ResultUtil<List<Map>>().setData(count);
    }

    @RequestMapping(value = "/getCenterOne", method = RequestMethod.GET)
    @ApiOperation(value = "获取巡河人员的平均里程")
    public Result<List<RiverAvg>> getCenterOne(){
        List<RiverAvg> list = iRiverTourHistoryService.getCenterOne();
        return new ResultUtil<List<RiverAvg>>().setData(list);
    }

    @RequestMapping(value = "/getZzData", method = RequestMethod.GET)
    @ApiOperation(value = "获取事件追踪数据")
    public Result<List<EventReport>> getZzData(){
        List<EventReport> list = iRiverTourHistoryService.findByAll();
        return new ResultUtil<List<EventReport>>().setData(list);
    }
}
